package com.mashibing.mall.product.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.nacos.api.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.mashibing.common.exception.ServiceException;
import com.mashibing.common.utils.PageUtils;
import com.mashibing.mall.product.dao.AttrAttrgroupRelationDao;
import com.mashibing.mall.product.entity.AttrAttrgroupRelationEntity;
import com.mashibing.mall.product.entity.AttrGroupEntity;
import com.mashibing.mall.product.entity.CategoryEntity;
import com.mashibing.mall.product.enums.ProductConstant;
import com.mashibing.mall.product.exception.AttrServiceExceptionEnum;
import com.mashibing.mall.product.param.AttrGroupRelationParam;
import com.mashibing.mall.product.param.AttributeParam;
import com.mashibing.mall.product.service.AttrAttrgroupRelationService;
import com.mashibing.mall.product.service.CategoryService;
import com.mashibing.mall.product.vo.AttrResponseVo;
import com.mashibing.mall.product.vo.AttrVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mashibing.common.utils.Query;

import com.mashibing.mall.product.dao.AttrDao;
import com.mashibing.mall.product.entity.AttrEntity;
import com.mashibing.mall.product.service.AttrService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;


/**
 * 商品属性 Service 实现类
 *
 * @author ROGzhongyang
 * @date 2024/12/2 09:27:16
 */
@Transactional
@Service("attrService")
public class AttrServiceImpl extends ServiceImpl<AttrDao, AttrEntity> implements AttrService {

    @Resource
    private AttrAttrgroupRelationService attrAttrgroupRelationService;
    @Autowired
    private AttrGroupServiceImpl attrGroupService;
    @Autowired
    private AttrAttrgroupRelationDao attrAttrgroupRelationDao;
    @Autowired
    private CategoryService categoryService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                new QueryWrapper<>()
        );

        return new PageUtils(page);
    }

    /**
     * 商品属性 - 规格参数新增
     */
    @Override
    public void add(AttributeParam attributeParam) {

        // 获取指定属性名称和分类 id 的属性列表
        LambdaQueryWrapper<AttrEntity> attrEntityQw = new LambdaQueryWrapper<>();
        attrEntityQw.eq(AttrEntity::getCatelogId, attributeParam.getCatelogId());
        attrEntityQw.eq(AttrEntity::getAttrName, attributeParam.getAttrName());
        List<AttrEntity> attrList = this.list(attrEntityQw);

        // 相同分类下，属性名不能重复
        if (!attrList.isEmpty()) {
            throw new ServiceException(AttrServiceExceptionEnum.ATTRNAME_EXIST_IN_SAME_CATELOG_ID);
        }

        AttrEntity entity = new AttrEntity();
        BeanUtils.copyProperties(attributeParam, entity);
        this.save(entity);

        // 如果属性分组 id 不为空
        if (ObjectUtil.isNotEmpty(attributeParam.getAttrGroupId())) {
            // todo 属性分组中，不能出现重复的属性

            AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
            // 设置相关属性
            relationEntity.setAttrId(entity.getAttrId());
            relationEntity.setAttrGroupId(attributeParam.getAttrGroupId());
            // 绑定属性与属性分组
            attrAttrgroupRelationService.save(relationEntity);
        }
    }

    /**
     * 商品属性 - 根据属性组 id 查询关联属性
     */
    @Override
    public List<AttrEntity> getRelationAttr(Long attrgroupId) {
        // 1. 根据属性组编号从 属性组和基本信息的关联表中查询出对应的属性信息
        LambdaQueryWrapper<AttrAttrgroupRelationEntity> attrRelationQw = new LambdaQueryWrapper<>();
        attrRelationQw.eq(AttrAttrgroupRelationEntity::getAttrGroupId, attrgroupId);
        List<AttrAttrgroupRelationEntity> list = attrAttrgroupRelationService.list(attrRelationQw);
        if (CollectionUtil.isNotEmpty(list)) {
            // 2.根据属性id数组获取对应的详情信息
            Set<Long> attrSet = list.stream().map(AttrAttrgroupRelationEntity::getAttrId).collect(Collectors.toSet());
            LambdaQueryWrapper<AttrEntity> attrQw = new LambdaQueryWrapper<>();
            attrQw.in(AttrEntity::getAttrId, attrSet);
            return this.list(attrQw);
        }
       return new ArrayList<>();
    }

    /**
     * 商品属性 - 解除属性关联
     */
    @Override
    public void unRelateAttr(List<AttrGroupRelationParam> params) {
        List<AttrAttrgroupRelationEntity> list = new ArrayList<>();
        BeanUtils.copyProperties(params, list);
        attrAttrgroupRelationDao.removeBatchRelation(list);
    }

    /**
     * 商品属性 - 获取尚未与属性分组关联的属性
     */
    @Override
    public PageUtils getNoAttrRelation(Long attrgroupId, Map<String, Object> params) {

        // 根据属性分组 id 获取属性分组实体
        AttrGroupEntity attrGroup = attrGroupService.getById(attrgroupId);

        // 获取分类 id
        Long catelogId = attrGroup.getCatelogId();

        // 获取当前分类下所有的分组 id 集合
        LambdaQueryWrapper<AttrGroupEntity> attrGroupQw = new LambdaQueryWrapper<>();
        attrGroupQw.eq(AttrGroupEntity::getCatelogId, catelogId);
        Set<Long> attrGroupIdSet = attrGroupService.list(attrGroupQw).stream().map(AttrGroupEntity::getAttrGroupId).collect(Collectors.toSet());

        // 获取已经关联分组 id 集合的属性 id 集合
        LambdaQueryWrapper<AttrAttrgroupRelationEntity> attrGroupRelationQw = new LambdaQueryWrapper<>();
        attrGroupRelationQw.in(AttrAttrgroupRelationEntity::getAttrGroupId, attrGroupIdSet);
        Set<Long> relatedAttrIdSet = attrAttrgroupRelationService.list(attrGroupRelationQw).stream().map(AttrAttrgroupRelationEntity::getAttrId).collect(Collectors.toSet());

        // 获取当前分类下所有的属性 id 集合，并排除上述已经关联的属性 id 集合
        LambdaQueryWrapper<AttrEntity> attrQw = new LambdaQueryWrapper<>();
        attrQw.eq(AttrEntity::getCatelogId, catelogId);
        attrQw.eq(AttrEntity::getAttrType, ProductConstant.ATTR_TYPE_BASE.getCode()); // 只查询基本属性
        if (CollectionUtil.isNotEmpty(relatedAttrIdSet)) {
            attrQw.notIn(AttrEntity::getAttrId, relatedAttrIdSet); // 排除已关联的属性
        }
        String key = (String)params.get("key");
        if (!StrUtil.isEmpty(key)) {
            attrQw.and(w -> {
                w.eq(AttrEntity::getAttrId, key).or().like(AttrEntity::getAttrName, key); // 过滤查询条件
            });
        }
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                attrQw
        );

        return new PageUtils(page);
    }

    /**
     * 商品属性(规格参数、销售属性) - 分页
     */
    @Override
    public PageUtils queryBasePage(Map<String, Object> params, Long catelogId, String attrType) {
        QueryWrapper<AttrEntity> attrQw = new QueryWrapper<>();
        attrQw.eq("attr_type","base".equalsIgnoreCase(attrType)?1:0);
        // 根据类别 id 查询
        if (catelogId != 0) {
            attrQw.eq("catelog_id", catelogId);
        }
        // 根据 key 模糊查询
        String key = (String) params.get("key");
        if (!StringUtils.isEmpty(key)){
            attrQw.and(w -> {
                w.eq("attr_id", key).or().eq("attr_id", key);
            });
        }
        // 3.分页查询
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                attrQw
        );
        PageUtils pageUtils = new PageUtils(page);
        // 4. 关联的我们需要查询出类别名称和属性组的名称
        List<AttrEntity> records = page.getRecords();
        List<Object> list = records.stream().map(attrEntity -> {
            AttrResponseVo responseVo = new AttrResponseVo();
            BeanUtils.copyProperties(attrEntity, responseVo);
            // 查询每一条结果对应的 类别名称和属性组的名称
            CategoryEntity category = categoryService.getById(attrEntity.getCatelogId());
            if (ObjectUtil.isNotEmpty(category)) {
                responseVo.setCatelogName(category.getName());
            }
            if("base".equalsIgnoreCase(attrType)){
                // 设置属性组的名称
                AttrAttrgroupRelationEntity entity = new AttrAttrgroupRelationEntity();
                entity.setAttrId(attrEntity.getAttrId());
                // 去关联表中找到对应的属性组ID
                AttrAttrgroupRelationEntity attrAttrgroupRelationEntity = attrAttrgroupRelationDao
                        .selectOne(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attrEntity.getAttrId()));
                if (attrAttrgroupRelationEntity != null && attrAttrgroupRelationEntity.getAttrGroupId() != null) {
                    // 获取到属性组的ID，然后根据属性组的ID我们来查询属性组的名称
                    AttrGroupEntity attrGroupEntity = attrGroupService.getById(attrAttrgroupRelationEntity.getAttrGroupId());
                    responseVo.setGroupName(attrGroupEntity.getAttrGroupName());
                }
            }
            return responseVo;
        }).collect(Collectors.toList());
        pageUtils.setList(list);
        return pageUtils;
    }


    /**
     * 商品规格参数 - 详情
     */
    @Override
    public AttrResponseVo detail(Long attrId) {
        AttrResponseVo responseVo = new AttrResponseVo();
        // 根据商品规格参数
        AttrEntity attrEntity = this.getById(attrId);
        BeanUtils.copyProperties(attrEntity, responseVo);
        // 查询属性与属性关联信息
        AttrAttrgroupRelationEntity relationEntity = attrAttrgroupRelationService.getBaseMapper().selectOne(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attrId));
        if (ObjectUtil.isNotEmpty(relationEntity)) {
            // 获取属性组
            AttrGroupEntity attrGroup = attrGroupService.getById(relationEntity.getAttrGroupId());
            // 设置属性组 id
            responseVo.setAttrGroupId(attrGroup.getAttrGroupId());
            if (ObjectUtil.isNotEmpty(attrGroup)) {
                // 设置属性组名称
                responseVo.setGroupName(attrGroup.getAttrGroupName());
            }
        }
        // 查询当前商品规则参数关联的类别全路径
        Long catelogId = attrEntity.getCatelogId();
        Long[] catelogPath = categoryService.findCatelogPath(catelogId);
        responseVo.setCatelogPath(catelogPath);

        // 查询查询当前商品规则参数关联的类别
        CategoryEntity category = categoryService.getById(catelogId);
        if (ObjectUtil.isNotEmpty(category)) {
            responseVo.setCatelogName(category.getName());
        }
        return responseVo;
    }

    /**
     * 商品规格参数 - 编辑
     */
    @Transactional
    @Override
    public void edit(AttrVO attrVO) {
        AttrEntity attrEntity = new AttrEntity();
        BeanUtils.copyProperties(attrVO, attrEntity);
        // 更新主表数据
        this.updateById(attrEntity);
        // 构建待更新或新增的属性&属性关联
        AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
        relationEntity.setAttrId(attrEntity.getAttrId());
        relationEntity.setAttrGroupId(attrVO.getAttrGroupId());
        // 获取上述对应的新增的属性&属性关联数据的数量
        Integer count = attrAttrgroupRelationService.getBaseMapper().selectCount(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attrVO.getAttrId()));
        // 如果数量大于 0，进行更新
        if (count > 0) {
            attrAttrgroupRelationService.update(relationEntity, new UpdateWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attrVO.getAttrId()));
        }
        // 否则，进行插入
        else {
            attrAttrgroupRelationService.save(relationEntity);
        }
    }
}
